package study.ready;

import org.springframework.boot.actuate.audit.*;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.health.contributor.*;
import org.springframework.boot.restclient.RestClientCustomizer;
import org.springframework.context.annotation.*;
import org.springframework.core.env.Environment;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.core.userdetails.*;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.web.client.RestClient;

@Configuration(proxyBeanMethods=false)
class ReadyConfiguration {
  @Bean RecordingExporter recordingExporter(){return new RecordingExporter();}
  @Bean RestClientCustomizer labHeader(){return builder->builder.defaultHeader("X-U24-Client","auto-customizer");}
  @Bean @ConditionalOnProperty(name="lab.audit",havingValue="true",matchIfMissing=true)
  InMemoryAuditEventRepository auditRepository(){var repository=new InMemoryAuditEventRepository();repository.setCapacity(64);return repository;}
  @Bean HealthIndicator orderDependencyHealthIndicator(Environment env){
    String url=env.getRequiredProperty("lab.dependency-url");
    return ()->{try{String response=RestClient.create().get().uri(url).retrieve().body(String.class);return "up".equals(response)?Health.up().build():Health.down().withDetail("reason","unexpected synthetic dependency body").build();}catch(RuntimeException error){return Health.down().withDetail("failure",error.getClass().getSimpleName()).build();}};
  }
  @Configuration(proxyBeanMethods=false)
  @ConditionalOnProperty(name="lab.custom-security",havingValue="true")
  static class CustomSecurity {
    @Bean UserDetailsService users(){return new InMemoryUserDetailsManager(User.withUsername("ops").password("{noop}ops-password").roles("OPS").build(),User.withUsername("reader").password("{noop}reader-password").roles("READER").build());}
    @Bean SecurityFilterChain customChain(HttpSecurity http)throws Exception{
      http.authorizeHttpRequests(auth->auth.requestMatchers("/actuator/health/**","/livez","/readyz","/lab/open","/lab/gated").permitAll().requestMatchers("/actuator/**","/lab/**").hasRole("OPS").anyRequest().authenticated());
      http.httpBasic(Customizer.withDefaults());return http.build();
    }
  }
}
